from typing import List, Optional
import logging
from tortoise.exceptions import DoesNotExist, IntegrityError
from tortoise.transactions import atomic
from app.services.base_service import BaseService
from app.models.warehouse_models import Warehouse
from app.schemas.warehouse_schemas import WarehouseCreate, WarehouseUpdate

logger = logging.getLogger(__name__)

class WarehouseService(BaseService):
    """仓库服务类"""
    
    def __init__(self):
        super().__init__(Warehouse)
        
    @classmethod
    async def check_warehouse_exists(cls, name: str, address: str) -> bool:
        """检查仓库是否已存在"""
        logger = logging.getLogger(f"{__name__}.{cls.__name__}")
        try:
            logger.debug(f"检查仓库是否存在: name={name}, address={address}")
            exists = await Warehouse.filter(name=name, address=address).exists()
            if exists:
                logger.warning(f"仓库已存在: name={name}, address={address}")
            return exists
        except Exception as e:
            logger.error(f"检查仓库存在性失败: {str(e)}", exc_info=True)
            raise

    @classmethod
    @atomic()
    async def create_warehouse(cls, warehouse_data: WarehouseCreate) -> Warehouse:
        """创建新仓库"""
        try:
            logger.info(f"开始创建仓库: {warehouse_data.model_dump()}")
            exists = await cls.check_warehouse_exists(
                warehouse_data.name, 
                warehouse_data.address
            )
            if exists:
                msg = f"仓库已存在: name={warehouse_data.name}, address={warehouse_data.address}"
                logger.error(msg)
                raise ValueError(msg)
            
            warehouse = await Warehouse.create(**warehouse_data.model_dump(exclude_unset=True))
            await warehouse.refresh_from_db()
            logger.info(f"仓库创建成功: id={warehouse.id}")
            return warehouse
            
        except Exception as e:
            logger.error(f"创建仓库失败: {str(e)}", exc_info=True)
            raise

    @classmethod
    async def get_warehouse(cls, warehouse_id: int) -> Optional[Warehouse]:
        """根据ID获取仓库"""
        try:
            logger.debug(f"获取仓库信息: id={warehouse_id}")
            warehouse = await Warehouse.get_or_none(id=warehouse_id)
            if not warehouse:
                logger.warning(f"仓库不存在: id={warehouse_id}")
            return warehouse
        except Exception as e:
            logger.error(f"获取仓库信息失败: {str(e)}", exc_info=True)
            raise

    @classmethod
    async def list_warehouses(
        cls,
        skip: int = 0,
        limit: int = 10,
        name: Optional[str] = None,
        address: Optional[str] = None
    ) -> List[Warehouse]:
        """
        获取仓库列表，支持名称和地址筛选
        
        Args:
            skip: 跳过记录数，默认0
            limit: 返回记录数，默认10
            name: 仓库名称，可选的筛选条件
            address: 仓库地址，可选的筛选条件
            
        Returns:
            List[Warehouse]: 仓库列表
        """
        query = Warehouse.all()
        
        # 添加筛选条件
        if name:
            query = query.filter(name__icontains=name)  # 使用不区分大小写的包含查询
        if address:
            query = query.filter(address__icontains=address)
        
        return await query.offset(skip).limit(limit)

    @classmethod
    @atomic()
    async def update_warehouse(cls, warehouse_id: int, warehouse_data: WarehouseUpdate) -> Optional[Warehouse]:
        """
        更新仓库信息
        
        Args:
            warehouse_id: 仓库ID
            warehouse_data: 更新数据
            
        Returns:
            Optional[Warehouse]: 更新后的仓库实例或None
            
        Raises:
            Exception: 更新失败时抛出异常
        """
        try:
            warehouse = await cls.get_warehouse(warehouse_id)
            if warehouse:
                await warehouse.update_from_dict(warehouse_data.model_dump(exclude_unset=True))
                await warehouse.save()
                # 强制刷新以确保数据已更新
                await warehouse.refresh_from_db()
                return warehouse
            return None
        except Exception as e:
            raise Exception(f"更新仓库失败: {str(e)}") 